package pcloud.httpclient.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;


public class HttpStreamUploader
{
	public static final int blockSize = 4096;
	
	HttpURLConnection getHttpConnection(String urlString) throws Exception  
    {  
        URL url = new URL(urlString);  
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
        if ("https".equalsIgnoreCase(url.getProtocol()))      
        {  
            HttpsURLConnection httpsConn=(HttpsURLConnection) conn;  
            TrustManager[] managers ={new MyX509TrustManager()};  
            SSLContext sslContext=SSLContext.getInstance("TLS");  
            sslContext.init(null, managers, new SecureRandom());  
            SSLSocketFactory ssf=sslContext.getSocketFactory();  
            httpsConn.setSSLSocketFactory(ssf);  
            httpsConn.setHostnameVerifier(new MyHostnameVerifier());  
            return httpsConn;  
        }  
        else  
        {  
            return conn;  
        }  
    }  
	
	public void upload(String urlString, String username, String password, File f)
	{

		String BOUNDARY = "---------------------------41184676334";  
		byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();  

		StringBuffer sb = new StringBuffer();  
		  
		sb.append("--").append(BOUNDARY).append("\r\n");  
		sb.append("Content-Disposition: form-data; name=\"username\"\r\n\r\n");  
		sb.append(username);  
		sb.append("\r\n--").append(BOUNDARY).append("\r\n");  
		  
		sb.append("--").append(BOUNDARY).append("\r\n");  
		sb.append("Content-Disposition: form-data; name=\"password\"\r\n\r\n");  
		sb.append(password);  
		sb.append("\r\n--").append(BOUNDARY).append("\r\n");  
		  
		sb.append("--").append(BOUNDARY).append("\r\n");  
		sb.append("Content-Disposition: form-data; name=\"fileContent\"; filename=\"identify.zip\"\r\n");  
		sb.append("Content-Type: application/octet-stream\r\n\r\n");  
		  
		byte[] data = sb.toString().getBytes();  
		long fLen = f.length();  
		long contentLen = data.length + fLen + end_data.length;  

		HttpURLConnection conn;
		try {
			conn = getHttpConnection(urlString);  
			conn.setDoOutput(true);  
			conn.setDoInput(true);  
			conn.setRequestMethod("POST");
			conn.setRequestProperty("connection", "Keep-Alive");  
			conn.setRequestProperty("Charsert", "UTF-8");  
			conn.setRequestProperty("user-agent",  
			                    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0");                        //可以不指定  
			conn.setRequestProperty("Content-Type",  
			                    "multipart/form-data; boundary=" + BOUNDARY);  
			conn.setRequestProperty("Content-Length",  
			                    String.valueOf(contentLen));  //不清楚长度，可以不写  
			              
			conn.setAllowUserInteraction(false);    //无需用户交互，即弹出https等的对话框。  
			conn.setChunkedStreamingMode(blockSize);   //告诉HttpUrlConnection,我们需要采用流方式上传数据，无需本地缓存数据。HttpUrlConnection默认是将所有数据读到本地缓存，然后再发送给服务器，这样上传大文件时就会导致内存溢出。  
			OutputStream os = conn.getOutputStream();
			os.write(data);  //发送非文件数据  
			              
			InputStream fis = new FileInputStream(f);  //读取文件内容，发送数据，数据要一点点发送，不能一下全部读取发送，否则会内存溢出。  
			int rn;  
			byte[] buf = new byte[blockSize];    
			while ((rn = fis.read(buf, 0, blockSize)) > 0) {  
			    os.write(buf, 0, rn);  
			}  
			os.write(end_data);  
			os.flush();  
			os.close();  
			fis.close();
			  
		} catch (ProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
